`include "common_header.verilog" 
//  *************************************************************************
//  File : p8264_mix_control.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2010 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Denis Poverennyy
//  info@morethanip.com
//  *************************************************************************
//  Description : This block consists of
//              
//               - Reset Sync Logic
//               - Signal Detect Sync Logic
//               
//  Version     : $Id: p8264_mix_control.v,v 1.4 2014/10/09 14:58:07 dk Exp $
//  *************************************************************************

module p8264_mix_control (

        reset_rxclk,
        cgmii_rxclk,
        mld_rst_ref,
        lane_active,
        mld_rst_done_ref,
        signal_det_ref,
`ifdef MTIPPCS_FEC_ENA
        fec_ena_ref,
  `ifdef MTIPPCS_FECERR_ENA
                fec_err_ena_ref,
  `endif
        fec_locked_ref,
        fec_cerr_ref,
        fec_ncerr_ref,
        `ifdef MTIPPCS82_EEE_ENA
                fec_fastlock_ref,
        `endif
`endif   
        reset_sd_rx_clk,
        sd_rx_clk,
        signal_det_sd,
`ifdef MTIPPCS_FEC_ENA
        fec_ena_sd,
        `ifdef MTIPPCS_FECERR_ENA
                fec_err_ena_sd,
        `endif
        fec_locked_sd,
        fec_cerr_sd,
        fec_ncerr_sd,
        `ifdef MTIPPCS82_EEE_ENA
                fec_fastlock_sd,
        `endif
`endif  
`ifdef MTIPPCS82_EEE_ENA
        rx_mode_quiet_ref,
        rx_mode_quiet_sd,
        ram_period_ref,
        ram_period_sd,
`endif
        block_lock_sd,
        block_lock_ref,
        mld_rst_sd,
        desk_buf_rst_rd,
        desk_buf_rst_wr
                        );

input           reset_rxclk;            //  async active
input           cgmii_rxclk;            //  Reference clock
input           mld_rst_ref;            //  sw reset in the reference clock domain
input   [3:0]   lane_active;		//  Current active lanes
output  [3:0]   mld_rst_done_ref;       //  sw reset done in the reference clock domain        
output  [3:0]   signal_det_ref;         //  Block Lock in the reference clock domain  
`ifdef MTIPPCS_FEC_ENA
input   [3:0]   fec_ena_ref; 
        `ifdef MTIPPCS_FECERR_ENA
        input   [3:0]   fec_err_ena_ref; 
        `endif
output  [3:0]   fec_locked_ref; 
output  [3:0]   fec_cerr_ref; 
output  [3:0]   fec_ncerr_ref; 
        `ifdef MTIPPCS82_EEE_ENA
        input   [3:0]   fec_fastlock_ref;       //  if set, allows fast FEC lock acquisition procedure. The signal set when
        `endif                                  //  LPI SM in the RX_WAKE state
`endif
input   [3:0]   reset_sd_rx_clk;        //  async active high reset
input   [3:0]   sd_rx_clk;              //  Serdes clock
input   [3:0]   signal_det_sd;          //   signal detect in the serdes domain  
`ifdef MTIPPCS_FEC_ENA
output  [3:0]   fec_ena_sd; 
`ifdef MTIPPCS_FECERR_ENA
output  [3:0]   fec_err_ena_sd; 
`endif
`ifdef MTIPPCS82_EEE_ENA
output  [3:0]   fec_fastlock_sd;        //  if set, allows fast FEC lock acquisition procedure. The signal set when
`endif                                  //  LPI SM in the RX_WAKE state

input   [3:0]   fec_locked_sd; 
input   [3:0]   fec_cerr_sd; 
input   [3:0]   fec_ncerr_sd; 
`endif
`ifdef MTIPPCS82_EEE_ENA
input           rx_mode_quiet_ref;      // Indication that the remote has disabled its transmitter
output  [3:0]   rx_mode_quiet_sd;       // Indication that the remote has disabled its transmitter
input           ram_period_ref;         // if set the RAM is expected;
output  [3:0]   ram_period_sd;          // if set the RAM is expected;

`endif
input   [3:0]   block_lock_sd;             // block lock for indications
output  [3:0]   block_lock_ref;
output  [3:0]   mld_rst_sd; 

output  [3:0]   desk_buf_rst_rd;        // buffer reset in the core clock domain
output  [3:0]   desk_buf_rst_wr;        // buffer reset in the serdes clock domains

// out wires

wire    [3:0]   mld_rst_done_ref;       //  sw reset done in the reference clock domain        
wire    [3:0]   signal_det_ref;         //  Block Lock in the reference clock domain  
`ifdef MTIPPCS_FEC_ENA
wire    [3:0]   fec_locked_ref; 
wire    [3:0]   fec_cerr_ref; 
wire    [3:0]   fec_ncerr_ref; 
`endif
`ifdef MTIPPCS_FEC_ENA
wire    [3:0]   fec_ena_sd; 
`ifdef MTIPPCS_FECERR_ENA
wire    [3:0]   fec_err_ena_sd; 
`endif
`ifdef MTIPPCS82_EEE_ENA
wire    [3:0]   fec_fastlock_sd;        //  if set, allows fast FEC lock acquisition procedure. The signal set when
`endif                                  //  LPI SM in the RX_WAKE state
`endif
`ifdef MTIPPCS82_EEE_ENA
wire    [3:0]   rx_mode_quiet_sd;       // Indication that the remote has disabled its transmitter
wire    [3:0]   ram_period_sd;          // if set the RAM is expected;
`endif
wire    [3:0]   block_lock_ref;
wire    [3:0]   mld_rst_sd; 
wire    [3:0]   desk_buf_rst_rd;        // buffer reset in the core clock domain
wire    [3:0]   desk_buf_rst_wr;        // buffer reset in the serdes clock domains


wire 	[3:0] mld_rst_ref_ln;

assign mld_rst_sd = desk_buf_rst_wr;

assign mld_rst_ref_ln = {mld_rst_ref&&lane_active[3], mld_rst_ref&&lane_active[2], mld_rst_ref&&lane_active[1], mld_rst_ref&&lane_active[0]};

genvar sy;
generate for(sy=0; sy< 4; sy=sy+1)
begin:gen_rx_sy

ff_sreset U_RST_REF_TO_SERD (
        .reset_lclk     (reset_rxclk),
        .lclk           (cgmii_rxclk),
        .lsreset_in     (mld_rst_ref_ln[sy]),
        .lsreset_done   (mld_rst_done_ref[sy]),
        .lsreset_out    (desk_buf_rst_rd[sy]),
        .reset_oclk     (reset_sd_rx_clk[sy]),
        .oclk           (sd_rx_clk[sy]),
        .osreset_out    (desk_buf_rst_wr[sy]));
          
          
//  Clock domain crossing
//  block lock stays high from Lock State is reached
//  enough to have just double clock re-synch

          
mtip_xsync #(1) U_SIGNAL_DET_SYNC (

        .data_in        (signal_det_sd[sy]),
        .reset          (reset_rxclk),
        .clk            (cgmii_rxclk),
        .data_s         (signal_det_ref[sy]));




mtip_xsync #(1) U_BLOCK_LOCK_SYNC (

        .data_in        (block_lock_sd[sy]),
        .reset          (reset_rxclk),
        .clk            (cgmii_rxclk),
        .data_s         (block_lock_ref[sy]));
        
`ifdef MTIPPCS_FEC_ENA

mtip_xsync #(1) U_FEC_ENA_SYNC (

          .data_in      (fec_ena_ref[sy]),
          .reset        (reset_sd_rx_clk[sy]),
          .clk          (sd_rx_clk[sy]),
          .data_s       (fec_ena_sd[sy]));

`ifdef MTIPPCS_FECERR_ENA          
mtip_xsync #(1) U_FEC_ERR_ENA_SYNC (

        .data_in        (fec_err_ena_ref[sy]),
        .reset          (reset_sd_rx_clk[sy]),
        .clk            (sd_rx_clk[sy]),
        .data_s         (fec_err_ena_sd[sy]));
`endif          
mtip_xsync #(1) U_FEC_LOCKED_SYNC (

        .data_in        (fec_locked_sd[sy]),
        .reset          (reset_rxclk),
        .clk            (cgmii_rxclk),
        .data_s         (fec_locked_ref[sy]));


redge_ckxing U_FEC_NCERR (	
        .reset          (reset_sd_rx_clk[sy]),
        .clk            (sd_rx_clk[sy]),
        .sig            (fec_ncerr_sd[sy]),
        .reset_clk_o    (reset_rxclk),
        .clk_o          (cgmii_rxclk),
        .sig_o          (fec_ncerr_ref[sy]));


redge_ckxing U_FEC_CERR (	
        .reset          (reset_sd_rx_clk[sy]),
        .clk            (sd_rx_clk[sy]),
        .sig            (fec_cerr_sd[sy]),
        .reset_clk_o    (reset_rxclk),
        .clk_o          (cgmii_rxclk),
        .sig_o          (fec_cerr_ref[sy]));


`ifdef MTIPPCS82_EEE_ENA
mtip_xsync #(1) U_FEC_FAST_LOCK_SYNC (

        .data_in        (fec_fastlock_ref[sy]),
        .reset          (reset_sd_rx_clk[sy]),
        .clk            (sd_rx_clk[sy]),
        .data_s         (fec_fastlock_sd[sy]));
`endif 



`endif
          

`ifdef MTIPPCS82_EEE_ENA

mtip_xsync #(2) U_FEC_RX_QUIET_SYNC (

        .data_in      ({rx_mode_quiet_ref, ram_period_ref}),
        .reset        (reset_sd_rx_clk[sy]),
        .clk          (sd_rx_clk[sy]),
        .data_s       ({rx_mode_quiet_sd[sy], ram_period_sd[sy]}));
`endif

end
endgenerate



endmodule // module p8264_mix_control.v

